昨天的文章中我們留下了一個小問題:
在 top level scope 寫出的方法可以直接呼叫,但為 private 方法;在 Object 中則是 public 方法,可以掛在 self 身上呼叫,也能直接呼叫,難道 main 某種程度上等同 Object?
在試著釐清這個問題之前,我們先來看看 Object 裡到底有哪些方法?
Object.instance_methods.count # 印出 58
這裡顯示 58 個,那麼這些方法又是哪裡來的呢?其實都是繼承自 BasicObject
以及 include 自 Kernel
來的
Kernel.instance_methods.count # 印出 50
BasicObject.instance_methods.count # 印出 8
那麼,這些方法是全部複製到 Object
中還是從 Object
再往上查找呢?
module Mod_A
def method
puts "from Mod_A"
end
end
class SuperKlass
def method
puts "from SuperKlass"
end
end
class Klass < SuperKlass
include Mod_A
end
obj = Klass.new
obj.method # 印出 from Mod_A
原來是後者,可以發現向上查找的順序其實是有彎就先轉
:
那麼我們能知道某個方法被寫在哪個類別或哪個模組裡嗎?
puts method(:instance_variable_set).owner # 印出 Kernel
找一個 Kernal
裡的方法來試試,可以發現 owner
這個方法可以找到方法的所屬位置,那麼我們回歸正題
def fat_thor
puts "I'm still worthy!"
end
method(:fat_thor).owner # 印出 Object
可以發現top level scope的方法真的是被寫在 Object
裡,不過被設定為 private method
。
但,真的是 private 嗎?回顧一下昨天,打開 irb 重新寫一遍:
def fat_thor
puts " I'm still worthy! "
end
fat_thor # 印出 I'm still worthy!
self.fat_thor # 印出 I'm still worthy!
在 top level scope 定義方法可以直接使用或是省略 self
,那這不是 public 方法的特徵嗎?難道這是因為在編輯器裡所有的實體都能使用 top level scope 的方法太危險了才加的保險裝置?抑或是為了方便在 irb
測試而作為 public 呢?
此文同步刊登於CJ-Han的網站